#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <string>
#include "Fail.hpp"

class UdpClient
{
public:
    UdpClient(std::string ip, uint16_t port)
        : _ip(ip)
        , _port(port)
    {}

    void InitClient()
    {
        _sock = socket(AF_INET, SOCK_DGRAM, 0);
        if(_sock < 0)
        {
            perror("create socket fail");
            exit(SOCKET_FAIL);
        }
    }

    void Start()
    {
        struct sockaddr_in receiver;
        memset(&receiver, 0, sizeof(receiver));
        receiver.sin_family = AF_INET;
        receiver.sin_port = htons(_port);
        receiver.sin_addr.s_addr = inet_addr(_ip.c_str());

        while(true)
        {
            std::cout << "place enter# ";
            std::string message;
            getline(std::cin, message);

            if(sendto(_sock, message.c_str(), message.size(), 0, (struct sockaddr*)&receiver, sizeof(receiver)) < 0)
            {
                perror("sendto fail");
                exit(SENDTO_FAIL);
            }

            char buff[2048];
            struct sockaddr_in receiver_temp;
            socklen_t len = sizeof(receiver_temp);
            memset(&receiver_temp, 0, sizeof(receiver_temp));
            int n = recvfrom(_sock, buff, sizeof(buff) - 1, 0, (struct sockaddr*)&receiver_temp, &len);
            if(n > 0)
            {
                buff[n] = '\0';
            }
            std::cout << "server echo# " << buff << std::endl;
        }
    }

    ~UdpClient()
    {}

private:
    int _sock; //套接字
    std::string _ip;
    uint16_t _port; //端口
};
